package com.tianqu.tms.entity;

import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

import com.tianqu.tms.core.base.Logger;
import com.tianqu.tms.core.base.TmsEntity;
import com.tianqu.tms.core.exception.TmsDaoException;
import com.tianqu.tms.core.exception.TmsException;
import com.tianqu.tms.dao.SequenceDao;
import com.tianqu.tms.dao.TmsDao;
import com.tianqu.tms.dto.SequenceDto;

public class Sequence extends TmsEntity {
	private Logger LOGGER = Logger.getLogger(Sequence.class);
	private final static int INCREMENT = 50;
	private static final Sequence INSTANCE = new Sequence();
	private static ConcurrentMap<Integer, SequenceDto> map = new ConcurrentHashMap<Integer, SequenceDto>();
	
	private final static int TYPE_1 = 1;//库存车辆编号
	private final static int TYPE_2 = 2;//竞拍非库存车辆编号
	private final static int TYPE_3 = 3;//检测认证非库存车辆编号
	private final static int TYPE_4 = 4;//经办人会员编号
	private final static int TYPE_5 = 5;//过户非库存车辆编号
	private final static int TYPE_6 = 6;//过户流水号
	private final static int TYPE_7 = 7;//商户会员编号
	private final static int TYPE_8 = 8;//金融业务编号
	private final static int TYPE_9 = 9;//金融公司编号
	private Sequence(){};
	
	public synchronized static Sequence getInstance() {
		return INSTANCE;
	}
    
	/**
	 * 获得车辆ID
	 * 
	 * @return
	 * @throws TmsDaoException
	 * @throws InterruptedException
	 */
	public String getSerial(int type) throws TmsDaoException{
		synchronized (INSTANCE) {
			SequenceDto seq = map.get(type);
			String s = "";
			if (seq != null && seq.getOffset() < INCREMENT) {
				seq.setOffset(seq.getOffset() + 1);
				map.put(type, seq);
				int n = seq.getNowSerial() + seq.getOffset();
				s = seq.getPrefix() + n + seq.getPostfix();
			} else {
				SequenceDao dao = (SequenceDao) TmsDao.getInstance(TmsDao.TMS_SEQUENCE);
				SequenceDto dto = dao.getSerial(type);
				if (dto == null) {
					LOGGER.error("didn't find any data:type" + type);
					return "";
				}
				int nowSerial = fillingZero(dto.getNowSerial(), type);
				if (dto.getNowSerial() > dto.getEndnum()) {
					LOGGER.error("More than maximum,type:" + type);
					return "";
				}
				dto.setNowSerial(nowSerial);
				dao.updateSerial(dto.getType(), nowSerial + INCREMENT);
				dto.setOffset(1);
				map.put(type, dto);
				int n = nowSerial + dto.getOffset();
				s = dto.getPrefix() + n + dto.getPostfix();
			}
			LOGGER.debug("generate serial:" + s +" type:"+type);
			return s;
		}
	}
	

	private int fillingZero(int serial,int type){
		if(serial <= 0 ) serial = 1;
		int pow = 6;
		if(type == TYPE_1) pow = 6;
		else if(type == TYPE_2)  pow = 6;
		else if(type == TYPE_3)  pow = 6;
		else if(type == TYPE_4)  pow = 5;
		else if(type == TYPE_5)  pow = 6;
		else if(type == TYPE_6)  pow = 6;
		else if(type == TYPE_7)  pow = 5;
		else if(type == TYPE_8)  pow = 6;
		else if(type == TYPE_9)  pow = 5;
		else LOGGER.error("sequence invalid type:type"+type);
		int n = pow - String.valueOf(serial).length();
		if(n > 0)  serial = serial * (int) Math.pow(10,n);
		return serial;
	}
	
	@Override
	public void save() throws TmsDaoException, TmsException {}
}
